#include <iostream>
#include <valarray>
#include <string>

// 私有继承,(默认为private私有继承)
// 基类的公共成员和保护成员都将会成为派生类的私有成员
// 基类方法不会成为派生类公共接口的一部分,但是可以在派生类的成员函数中使用他们
class StudentClassI : private std::string, private std::valarray<double>
{
private:
    typedef std::valarray<double> ArrayDb;
    std::ostream &arr_out(std::ostream &os) const;

public:
    // 这样的声明将会使私有继承(保护继承)中的私有方法在本类中可用
    // 被称为 "使用using重新定义访问权限"
    using std::valarray<double>::max;
    using std::valarray<double>::min;
    using std::valarray<double>::operator[];
    // 不需要重新定义方法,将(基类)私有的方法声明成public,即可在本类中使用基类的方法

    StudentClassI() : std::string("Null Student"), ArrayDb() {}
    explicit StudentClassI(const std::string name) : std::string(name), ArrayDb() {}
    explicit StudentClassI(int n) : std::string("Nully"), ArrayDb(n) {}

    StudentClassI(const std::string &s, int n) : std::string("Nully"), ArrayDb(n) {}
    StudentClassI(const std::string &s, const ArrayDb &db) : std::string("Nully"), ArrayDb(db) {}
    StudentClassI(const char *s, const ArrayDb &db) : std::string(s), ArrayDb(db) {}
    StudentClassI(const char *s, const double *pd, int n) : std::string(s), ArrayDb(pd, n) {}
    ~StudentClassI() {}

    double Average() const;
    double &operator[](int i);
    double operator[](int i) const;
    const std::string &Name() const;

    // friend
    friend std::istream &operator>>(std::istream &is, StudentClassI &stui);
    friend std::istream &getline(std::istream &is, StudentClassI &stui);
    friend std::ostream &operator<<(std::ostream &os, const StudentClassI &stui);
};
